﻿using System.Data;
using System.Data.Common;

namespace Swimj.DataCore;

public interface IProvider
{
     /// <summary>
 ///     Gets the <seealso cref="IPagingHelper" /> this provider supplies.
 /// </summary>
 IPagingHelper PagingUtility { get; }

 /// <summary>
 ///     Gets a flag for whether the DB has native support for GUID/UUID.
 /// </summary>
 bool HasNativeGuidSupport { get; }

 /// <summary>
 ///     Escape a tablename into a suitable format for the associated database provider.
 /// </summary>
 /// <param name="tableName">
 ///     The name of the table (as specified by the client program, or as attributes on the associated
 ///     POCO class.
 /// </param>
 /// <returns>The escaped table name</returns>
 string EscapeTableName(string tableName);

 /// <summary>
 ///     Escape and arbitary SQL identifier into a format suitable for the associated database provider
 /// </summary>
 /// <param name="sqlIdentifier">The SQL identifier to be escaped</param>
 /// <returns>The escaped identifier</returns>
 string EscapeSqlIdentifier(string sqlIdentifier);

 /// <summary>
 ///     Builds an SQL query suitable for performing page based queries to the database
 /// </summary>
 /// <param name="skip">The number of rows that should be skipped by the query</param>
 /// <param name="take">The number of rows that should be retruend by the query</param>
 /// <param name="parts">The original SQL query after being parsed into it's component parts</param>
 /// <returns>The final SQL query that should be executed.</returns>
 string BuildPageQuery(long skip, long take, SqlParts parts);

 /// <summary>
 ///     Converts a supplied C# object value into a value suitable for passing to the database
 /// </summary>
 /// <param name="value">The value to convert</param>
 /// <returns>The converted value</returns>
 object MapParameterValue(object value);

 /// <summary>
 ///     Called immediately before a command is executed, allowing for modification of the IDbCommand before it's passed to
 ///     the database provider
 /// </summary>
 /// <param name="cmd"></param>
 void PreExecute(IDbCommand cmd);

 /// <summary>
 ///     Returns an SQL Statement that can check for the existence of a row in the database.
 /// </summary>
 /// <returns></returns>
 string GetExistsSql();

 /// <summary>
 ///     Returns an SQL expression that can be used to specify the return value of auto incremented columns.
 /// </summary>
 /// <param name="primaryKeyName">The primary key of the row being inserted.</param>
 /// <returns>An expression describing how to return the new primary key value</returns>
 /// <remarks>See the SQLServer database provider for an example of how this method is used.</remarks>
 string GetInsertOutputClause(string primaryKeyName);

 /// <summary>
 ///     Returns the prefix used to delimit parameters in SQL query strings.
 /// </summary>
 /// <param name="connectionString">The connection string.</param>
 /// <returns>The providers character for prefixing a query parameter.</returns>
 string GetParameterPrefix(string connectionString);

 DbProviderFactory GetFactory();
}